React 원리 : 왜 ref로 DOM 접근해야돼?

React에서 DOM을 직접 조작하면 안 되는 이유

Virtual DOM은 실제 DOM의 ‘청사진’ 일 뿐이다

React 컴포넌트가 JSX를 반환하면, 브라우저 DOM을 바로 만드는 것이 아니라 Virtual DOM이라는 가상의 객체가 먼저 만들어진다. 이 객체는 화면이 어떻게 보여야 하는지를 표현하는 청사진이며, React는 매 렌더링마다 이 청사진을 새로 만들어 이전 청사진과 비교한다. 그 차이점만 실제 DOM에 반영하는 방식이 React의 렌더링 모델이다.

즉, 개발자가 JSX를 작성할 때 다루는 것은 DOM이 아니라 “DOM의 모델”이다. 실제 DOM 요소는 React가 내부적으로 생성하고 관리한다. 따라서 일반적인 변수나 직접적인 DOM API로는 이 DOM에 접근할 수 없다.

실제 DOM 접근은 ref로 제한된다

React는 직접적인 DOM 접근이 필요한 경우를 위해 ref라는 접근 경로를 제공한다. ref는 React에게 “이 요소의 실제 DOM 노드를 알려줘”라고 요청하는 개념이며, React는 commit 단계에서 해당 DOM 노드를 ref.current에 연결해준다.

이 과정은 React 내부 렌더링 사이클에 통합되어 있어 안전하며, React가 DOM을 생성하는 타이밍과도 정확히 맞아떨어진다. 반면 일반 변수를 ref처럼 사용하려고 하면 React는 그 변수를 DOM 연결 대상이라고 인식하지 못하고, 당연히 DOM 노드를 할당해줄 수도 없다.


DOM 직접 조작이 React와 충돌하는 이유

React의 렌더링 로직은 Virtual DOM을 기준으로 “현재 화면이 이래야 한다”라고 판단한다. 그렇기 때문에 개발자가 React 밖에서 DOM을 조작하면, Virtual DOM과 실제 DOM이 서로 다른 상태가 된다.

이 상태를 desync라고 한다. 예를 들어 class를 DOM API로 추가한다고 해보자. Virtual DOM에는 그 class가 등록되지 않았는데, 실제 DOM에는 존재하게 된다. 이후 상태가 바뀌어 React가 다시 렌더링을 시도하면, Virtual DOM을 기준으로 다시 DOM을 패치해버린다. 결국 개발자가 수정한 DOM은 그대로 덮어씌워진다.

React 입장에서는 이 행동이 정상이지만, 개발자 입장에서는 “바꿔놓은 DOM이 다시 초기화되는 것처럼” 보인다.


React에서 DOM 조작을 피해야 하는 이유의 결론

React는 UI를 “상태의 결과물” 로 바라본다. 상태가 바뀌면 화면이 바뀌고, DOM은 이 상태 기반 모델의 결과로만 제어된다. Virtual DOM은 이 과정의 중심이며, 실제 DOM 조작은 React가 허용한 방식(ref) 외에는 모두 금기다.

직접 DOM을 건드릴 수는 있지만, 그 순간부터 React가 관리하는 Virtual DOM과 동기화가 깨지며, 최종적으로 React가 다시 렌더링하는 순간 모두 덮어씌워진다. DOM 조작은 최소한으로 제한해야 한다.